import java.io.*;
import java.net.*;
import java.util.*;

class Client 
{
   public static void main(String [] args) throws Exception
   {
String []adress = {"localhost","localhost","localhost","localhost"};
int    []ports  = {9001,9002,9003,9004};
	   
 if(args.length!=3 || args.length==0)
System.out.println("USAGE: java Client [MB.txt] [MC.txt] [MZ.txt]");
 else{	   
   new Client(args[0], args[1], args[2], adress, ports);  
 }
   }
  final static int HOST_COUNT=4;

  private double matrixA [][];
  private double matrixA1[][]; private double matrixA2[][];
  private double matrixA3[][]; private double matrixA4[][];
  
  private double matrixB [][];
  private double matrixC [][];

  private double matrixCZ[][];
  private double matrixCZ1[][]; private double matrixCZ2[][];
  private double matrixCZ3[][]; private double matrixCZ4[][];
  
  private double matrixZ[][];
  private double matrixZ1[][]; private double matrixZ2[][];
  private double matrixZ3[][]; private double matrixZ4[][];
  
  private int d1,d2,d3,d4;
	  
  Client(String f1, String f2, String f3, String [] adress, int [] ports) throws Exception
  {
  matrixB = new FileRead(f1).getMatrix();
  matrixC = new FileRead(f2).getMatrix();
  matrixZ = new FileRead(f3).getMatrix();
  
if(matrixB[0].length!=matrixC.length||matrixC[0].length!=matrixZ.length)
  { 
   System.out.println("Nevirnyy rozmir vyhidnyh danyh !!!\n");  
   System.exit(0); 
  }
  matrixA = new double[matrixB.length][matrixZ[0].length];
  
  if(matrixZ[0].length<HOST_COUNT)
   {
	   new NoName(matrixB,matrixC,matrixZ,adress,ports);
	   System.exit(0);
   }
  else
  {
  if(matrixZ[0].length%HOST_COUNT!=0)
{
int z=matrixZ[0].length%HOST_COUNT;int d=matrixZ[0].length/HOST_COUNT;
if(z==2){d1=d+1;d2=d+1;d3=d;d4=d;}
else{if(z==3){d1=d+1;d2=d+1;d3=d+1;d4=d;}else{d1=d+1;d2=d;d3=d;d4=d;}}
    }
      else
          { d1=d2=d3=d4=matrixZ[0].length/HOST_COUNT;  }
  }
  
  matrixZ1 = new double[matrixZ.length][d1]; 
  matrixZ2 = new double[matrixZ.length][d2]; 
  matrixZ3 = new double[matrixZ.length][d3]; 
  matrixZ4 = new double[matrixZ.length][d4]; 
 
  matrixCZ1= new double[matrixC.length][d1];
  matrixCZ2= new double[matrixC.length][d2];
  matrixCZ3= new double[matrixC.length][d3];
  matrixCZ4= new double[matrixC.length][d4];
  
  matrixA1 = new double[matrixB.length][d1]; 
  matrixA2 = new double[matrixB.length][d2]; 
  matrixA3 = new double[matrixB.length][d3]; 
  matrixA4 = new double[matrixB.length][d4]; 

for(int i=0;i<matrixZ.length;i++)
  for(int j=0;j<d1;j++) 
  matrixZ1[i][j] = matrixZ[i][j];
for(int i=0;i<matrixZ.length;i++)
  for(int k=d1,j=0;k<(d2+d1);k++,j++) 
  matrixZ2[i][j] = matrixZ[i][k]; 
for(int i=0;i<matrixZ.length;i++)
  for(int k=d2+d1,j=0;k<d3+d2+d1;k++,j++) 
  matrixZ3[i][j] = matrixZ[i][k]; 
for(int i=0;i<matrixZ.length;i++)
  for(int k=d3+d2+d1,j=0;k<d4+d3+d2+d1;k++,j++) 
  matrixZ4[i][j] = matrixZ[i][k]; 
System.out.print("Transferring data to MyHosts.......\n");
        Socket [] s = new Socket[HOST_COUNT];
	ObjectOutputStream []oos = new ObjectOutputStream[HOST_COUNT] ;
	ObjectInputStream  []ois = new ObjectInputStream[HOST_COUNT];
	try{
for(int i=0;i<HOST_COUNT;i++)
{
     s[i] = new Socket(adress[i],ports[i]);
   oos[i] = new ObjectOutputStream(s[i].getOutputStream());
   ois[i] = new ObjectInputStream(s[i].getInputStream());
 }
}catch(Exception e)
{System.out.println("network exceptions: "+e);}
try{
oos[0].writeObject(matrixC); oos[0].writeObject(matrixZ1); oos[0].flush();
System.out.println(" host1 ---->");
oos[1].writeObject(matrixC); oos[1].writeObject(matrixZ2); oos[1].flush();
System.out.println(" host2 ---->");
oos[2].writeObject(matrixC); oos[2].writeObject(matrixZ3); oos[2].flush();
System.out.println(" host3 ---->");
oos[3].writeObject(matrixC); oos[3].writeObject(matrixZ4); oos[3].flush();
System.out.println(" host4 ---->");
}catch(Exception e)
{System.out.println("network e(outC outZ): "+e);}
try{
matrixCZ1=(double [][])ois[0].readObject();
System.out.println(" host1<--");
matrixCZ2=(double [][])ois[1].readObject();
System.out.println(" host2<--");
matrixCZ3=(double [][])ois[2].readObject();
System.out.println(" host3<--");
matrixCZ4=(double [][])ois[3].readObject();
System.out.println(" host4<--");
}catch(Exception e)
{System.out.println("network e(inCZ): "+e);}

try{
oos[0].writeObject(matrixB); oos[0].writeObject(matrixCZ1); oos[0].flush(); 
System.out.println(" host1 oooo>");
oos[1].writeObject(matrixB); oos[1].writeObject(matrixCZ2); oos[1].flush(); 
System.out.println(" host2 oooo>");
oos[2].writeObject(matrixB); oos[2].writeObject(matrixCZ3); oos[2].flush();
System.out.println(" host3 oooo>");
oos[3].writeObject(matrixB); oos[3].writeObject(matrixCZ4); oos[3].flush();
System.out.println(" host4 oooo>");
}catch(Exception e)
{System.out.println("network e(outBCZ): "+e);}

try{
matrixA1=(double [][])ois[0].readObject();
System.out.println(" host1 <oooo");
matrixA2=(double [][])ois[1].readObject();
System.out.println(" host2 <oooo");
matrixA3=(double [][])ois[2].readObject();
System.out.println(" host3 <oooo");
matrixA4=(double [][])ois[3].readObject();
System.out.println(" host4 <oooo");
}catch(Exception e)
{System.out.println("network e(inA): "+e);}

for(int i=0;i<matrixA.length;i++)
  for(int j=0;j<d1;j++) 
  matrixA[i][j] = matrixA1[i][j];
for(int i=0;i<matrixA.length;i++)
  for(int k=d1,j=0;k<(d2+d1);k++,j++) 
  matrixA[i][k] = matrixA2[i][j]; 
for(int i=0;i<matrixA.length;i++)
  for(int k=d2+d1,j=0;k<d3+d2+d1;k++,j++) 
  matrixA[i][k] = matrixA3[i][j]; 
for(int i=0;i<matrixA.length;i++)
  for(int k=d3+d2+d1,j=0;k<d4+d3+d2+d1;k++,j++) 
  matrixA[i][k] = matrixA4[i][j]; 

  FileWriter fw = new FileWriter("result.txt",false);
for(int i=0;i<matrixA.length;i++)
{  for(int j=0;j<matrixA[0].length;j++)
  fw.write(matrixA[i][j]+" ");
  fw.write("\n");
}
  fw.close();
  }
}
